package com.atguigu.common.base.entity;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@MappedSuperclass
public class AutoIdBase extends TimestampBase {

    @Id
    @Column(nullable = false)
    private Long id;

    public static final Map<Class<? extends AutoIdBase>, AutoIdBase> CURRENT_ENTITIES = new HashMap<>();

    @Transient
    private boolean isNew = true;

    @Transient
    private boolean isModified = true;

    public AutoIdBase(LocalDateTime createTime) {
        super(createTime);
        setNew(true);
        setModified(true);
        generateId();
    }

    public void generateId() {
        if (id == null) {
            synchronized (CURRENT_ENTITIES) {
                AutoIdBase currentEntity = CURRENT_ENTITIES.get(this.getClass());
                if (currentEntity == null) {
                    currentEntity = new AutoIdBase(1);
                    CURRENT_ENTITIES.put(this.getClass(), currentEntity);
                }
                id = currentEntity.id;
                currentEntity.id++;
            }
        }
    }

    private AutoIdBase(long id) {
        this.id = id;
    }

    @PostLoad
    private void setCurrentId() {
        synchronized (CURRENT_ENTITIES) {
            AutoIdBase currentEntity = CURRENT_ENTITIES.get(this.getClass());
            if (currentEntity == null) {
                currentEntity = new AutoIdBase(1);
                CURRENT_ENTITIES.put(this.getClass(), currentEntity);
            }
            if (currentEntity.id <= id) {
                currentEntity.id = id + 1;
            }
        }
        setNew(false);
        setModified(false);
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        super.setUpdateTime(updateTime);
        setModified(true);
    }
}
